﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Noea.TogSim.Model.Interfaces
{
    /// <summary>
    /// Implements an engine for primary for updating position and speed of a trainset
    /// A external schedule/dispathing mechanism should call one of the class' UpdatePosition methods
    /// </summary>
    public interface ITrainEngine
    {
        /// <summary>
        /// Interval between updating the position
        /// </summary>
        int Interval { get; }
        /// <summary>
        /// Time stamp for last update of the position
        /// </summary>
        long PrevTime { get; set; }
        /// <summary>
        /// Simulation time elapsed for this Engine.
        /// </summary>
        double ElapsedTime { get; }
        /// <summary>
        /// get, set acceleration. When updating position, the speed should be updated according to acceleration
        /// </summary>
        double Acceleration { get; set; }
        /// <summary>
        /// UpdatePosition updates position on the track and the speed of the trainset.
        /// If the train set has moved to the next track, the TrainSet's CurrentTrack property must be updated.
        /// </summary>
        /// <param name="obj">Object with new current time</param>
        void UpdatePosition(Object obj);
        /// <summary>
        /// UpdatePosition updates position on the track and the speed of the trainset.
        /// If the train set has moved to the next track, the TrainSet's CurrentTrack property must be updated.
        /// </summary>
        /// <param name="secs">Elapsed time since last update</param>
        void UpdatePosition(double secs);
        /// <summary>
        /// Returns a Queue Object with the tracks, that train set blocks. 
        /// The front element in the queue is the first to be unblocked, which also is the last track in the driving direction
        /// </summary>
        System.Collections.Queue Tracks { get; }
        /// <summary>
        /// Gets the train set associated with the TrainEngine
        /// </summary>
        ITrainSet Train { get; }
        /// <summary>
        /// Gets front position of the trainset on current track
        /// </summary>
        double TrackPos { get; }
        /// <summary>
        /// Event handler for handling a change in the driving direction. 
        /// The queue has to be inverted.
        /// </summary>
        /// <param name="ts">Actual train set</param>
        /// <param name="args">Further information</param>
        void InvertDirection(ITrainSet ts, ITrainEventArgs args);

        /// <summary>
        /// Start the engine
        /// </summary>
        void Start();
        /// <summary>
        /// Start the engine
        /// </summary>
        /// <param name="updateFrequency">Requested update frequency = calls to UpdatePosition pr. sec. </param>
        void Start(double updateFrequency);
        /// <summary>
        /// Stops the engine
        /// </summary>
        void Stop();
        /// <summary>
        /// Get, sets requested update frequency = calls to UpdatePosition pr. sec.
        /// </summary>
        double UpdateFrequency { get; set; }
        /// <summary>
        /// Gets an array with blocked tracks by the train set.
        /// Index =0 references current track.
        /// </summary>
        /// <returns>a array with tracks</returns>
        ITrack[] TracksList();
    }
}
